#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "opus.h"

#define SAMPLE_RATE 16000  // 16 kHz
#define FRAME_SIZE 960     // 20ms 的音频数据
#define CHANNELS 1         // 单声道
#define MAX_PACKET_SIZE 1276  // Opus 数据包的最大大小

// WAV 文件头结构
typedef struct {
    char chunk_id[4];
    int chunk_size;
    char format[4];
    char subchunk1_id[4];
    int subchunk1_size;
    short audio_format;
    short num_channels;
    int sample_rate;
    int byte_rate;
    short block_align;
    short bits_per_sample;
    char subchunk2_id[4];
    int subchunk2_size;
} WavHeader;

int main() {
    OpusEncoder *encoder;
    int error;
    short pcm[FRAME_SIZE * CHANNELS];
    unsigned char opus_data[MAX_PACKET_SIZE];
    int opus_bytes;

    // 初始化 Opus 编码器
    encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, OPUS_APPLICATION_AUDIO, &error);
    if (error != OPUS_OK) {
        fprintf(stderr, "编码器初始化失败: %d\n", error);
        return 1;
    }

    // 读取 WAV 文件头
    WavHeader header;
    if (fread(&header, sizeof(header), 1, stdin) != 1) {
        fprintf(stderr, "无法读取 WAV 文件头\n");
        return 1;
    }

    // 检查 WAV 文件格式
    if (strncmp(header.chunk_id, "RIFF", 4) != 0 || strncmp(header.format, "WAVE", 4) != 0) {
        fprintf(stderr, "无效的 WAV 文件\n");
        return 1;
    }

    // 从标准输入读取 PCM 数据并编码
    while (1) {
        size_t bytes_read = fread(pcm, sizeof(short), FRAME_SIZE * CHANNELS, stdin);  // 从 stdin 读取 PCM 数据
        if (bytes_read == 0) break;

        // 编码 PCM 数据为 Opus
        opus_bytes = opus_encode(encoder, pcm, FRAME_SIZE, opus_data, MAX_PACKET_SIZE);
        if (opus_bytes < 0) {
            fprintf(stderr, "编码失败: %d\n", opus_bytes);
            break;
        }

        // 将编码后的 Opus 数据写入标准输出
        fwrite(opus_data, 1, opus_bytes, stdout);
    }

    // 销毁编码器
    opus_encoder_destroy(encoder);
    return 0;
}